package com.resrun.utils;

import com.resrun.model.CACert;
import org.apache.commons.io.FileUtils;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
import org.bouncycastle.operator.InputDecryptorProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS12SafeBag;
import org.bouncycastle.pkcs.PKCS12SafeBagBuilder;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.bouncycastle.pkcs.PKCSException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;

public class FileUtil {

    public static File getCertFileFromPEM(CACert cert) throws IOException {
        return getPEMFile(Base64.getEncoder().encodeToString(cert.getEncode()));
    }

    public static File getCertFileFromPKCS12(byte[] pfxBytes) throws IOException {
        return getPKCS12File(pfxBytes);
    }

    public static String getPEMContent(String certStr) {
        return "-----BEGIN CERTIFICATE-----\n" + lf(certStr, 64) + "-----END CERTIFICATE-----";
    }

    public static File getPEMFile(String certStr) throws IOException {
        File file = File.createTempFile("cert", ".pem");
        FileUtils.writeStringToFile(file, getPEMContent(certStr), StandardCharsets.UTF_8);

        return file;
    }

    public static File getDERFile(byte[] derBytes) throws IOException {
        File file = File.createTempFile("cert", ".der");
        try (FileOutputStream derFileOutputStream = new FileOutputStream(file)) {
            //derFileOutputStream.write(Base64.getDecoder().decode(certStr));
            derFileOutputStream.write(Base64.getDecoder().decode(derBytes));
        }

        return file;
    }

    public static File getPKCS12File(byte[] pfxBytes) throws IOException {
        File file = File.createTempFile("cert", ".pfx");
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(pfxBytes);
        }

        return file;
    }

    public static File getPKCS12File(String certStr) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, NoSuchProviderException, OperatorCreationException, PKCSException {
        String pemContent = getPEMContent(certStr);
        // 创建解析器读取PEM格式的内容
        PEMParser certParser = new PEMParser(new StringReader(pemContent));
        X509CertificateHolder certHolder = (X509CertificateHolder) certParser.readObject();
        JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter().setProvider("BC");
        X509Certificate x509Cert = certConverter.getCertificate(certHolder);

        PEMParser keyParser = new PEMParser(new StringReader("keyString"));
        Object parsedKeyObj = keyParser.readObject();
        JcaPEMKeyConverter keyConverter = new JcaPEMKeyConverter().setProvider("BC");

        PrivateKey privateKey = null;

        if (parsedKeyObj instanceof PrivateKeyInfo) {
            privateKey = keyConverter.getPrivateKey((PrivateKeyInfo) parsedKeyObj);
        } else if (parsedKeyObj instanceof PKCS8EncryptedPrivateKeyInfo) {
            // 解密私钥
            PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) parsedKeyObj;
            InputDecryptorProvider decryptionProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider("BC").build("password".toCharArray());
            PrivateKeyInfo privateKeyInfo = encryptedPrivateKeyInfo.decryptPrivateKeyInfo(decryptionProvider);

            // 将解密后的私钥转换为Java PrivateKey对象
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
            privateKey = converter.getPrivateKey(privateKeyInfo);
        }

        KeyStore pkcs12Keystore = KeyStore.getInstance("PKCS12", "BC");
        pkcs12Keystore.load(null, null);
        pkcs12Keystore.setKeyEntry("your-friendly-name", privateKey, "password".toCharArray(), new Certificate[]{x509Cert});

        // 将PKCS12存储到文件
        File file = File.createTempFile("cert", ".p12");
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            pkcs12Keystore.store(outputStream, "password".toCharArray());
        }

        return file;
    }

    public static String lf(String str, int lineLength) {
        if (str == null || lineLength <= 0) {
            return str;
        }

        StringBuilder sb = new StringBuilder();
        char[] chars = str.toCharArray();
        int n = 0;
        for (char aChar : chars) {
            sb.append(aChar);
            n++;
            if (n == lineLength) {
                n = 0;
                sb.append("\n");
            }
        }

        if (n != 0) {
            sb.append("\n");
        }

        return sb.toString();
    }

}
